package cn.iocoder.yudao.module.system.controller.admin.erp.sku;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.controller.admin.erp.sku.vo.SkuPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.erp.sku.vo.SkuRespExcel;
import cn.iocoder.yudao.module.system.controller.admin.erp.sku.vo.SkuRespVO;
import cn.iocoder.yudao.module.system.controller.admin.erp.sku.vo.SkuSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.erp.warehouse.vo.WarehouseRespVO;
import cn.iocoder.yudao.module.system.controller.admin.erp.warehouse.vo.WarehouseSaveReqVO;
import cn.iocoder.yudao.module.system.core.ErpOperationField;
import cn.iocoder.yudao.module.system.core.ErpOperationLog;
import cn.iocoder.yudao.module.system.dal.dataobject.erp.sku.SkuDO;
import cn.iocoder.yudao.module.system.service.erp.operatelog.ErpOperateLogService;
import cn.iocoder.yudao.module.system.service.erp.sku.SkuService;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;

import java.math.BigDecimal;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exceptionErr;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import org.springframework.web.multipart.MultipartFile;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static java.util.Arrays.asList;


@Tag(name = "管理后台 - 商品sku")
@RestController
@RequestMapping("/erp/sku")
@Validated
public class SkuController {

    @Resource
    private SkuService skuService;
    @Resource
    private ErpOperateLogService erpOperateLogService;

    @PostMapping("/create")
    @Operation(summary = "创建商品sku")
    @PreAuthorize("@ss.hasPermission('erp:sku:create')")
    @ErpOperationLog(module = "SKU管理",description = "创建SKU")
    public CommonResult<Long> createSku(@Valid @RequestBody SkuSaveReqVO createReqVO) throws NoSuchMethodException {
        String sku = createReqVO.getSku();
        BigDecimal length = createReqVO.getLength();
        BigDecimal weight = createReqVO.getWeight();
        BigDecimal width = createReqVO.getWidth();
        BigDecimal height = createReqVO.getHeight();
        if(StrUtil.isBlank(sku)){
            throw exceptionErr(500,"sku不能为空");
        }
        SkuDO dbItem = skuService.getSku(sku);
        if(ObjectUtil.isNotNull(dbItem)){
            throw exceptionErr(500,"sku已存在");
        }

        if(Stream.of(length, weight, width, height).anyMatch(e -> ObjectUtil.isNull(e) || e.compareTo(BigDecimal.ZERO) == 0)){
            throw exceptionErr(500,"长|宽|高|重量|不能为空");
        }


        Long skuId = skuService.createSku(createReqVO);
        WarehouseRespVO respVO = BeanUtils.toBean(skuService.getSku(skuId), WarehouseRespVO.class);
        String content=" "+Arrays.stream(respVO.getClass().getDeclaredFields()).filter(field->ObjectUtil.isNotNull(field.getAnnotation(ErpOperationField.class))
        ).map(field -> {field.setAccessible(true);try{
            return field.getAnnotation(ErpOperationField.class).name() + ":" + field.get(respVO);
        } catch (IllegalAccessException e) {throw new RuntimeException(e);}
        }).collect(Collectors.joining(","));
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("createSku",SkuSaveReqVO.class));
        return success(skuId);
    }

    @PutMapping("/update")
    @Operation(summary = "更新商品sku")
    @PreAuthorize("@ss.hasPermission('erp:sku:update')")
    @ErpOperationLog(module = "SKU管理",description = "修改SKU")
    public CommonResult<Boolean> updateSku(@Valid @RequestBody SkuSaveReqVO updateReqVO) throws NoSuchMethodException {
        String sku = updateReqVO.getSku();
        BigDecimal length = updateReqVO.getLength();
        BigDecimal weight = updateReqVO.getWeight();
        BigDecimal width = updateReqVO.getWidth();
        BigDecimal height = updateReqVO.getHeight();
        if(StrUtil.isBlank(sku)){
            throw exceptionErr(500,"sku不能为空");
        }
        SkuDO dbItem = skuService.getSku(sku);
        if(ObjectUtil.isNotNull(dbItem)&&!ObjectUtil.equal(dbItem.getId(),updateReqVO.getId())){
            throw exceptionErr(500,"sku已存在");
        }

        if(Stream.of(length, weight, width, height).anyMatch(e ->ObjectUtil.isNull(e) || e.compareTo(BigDecimal.ZERO) == 0)){
            throw exceptionErr(500,"长|宽|高|重量|不能为空");
        }
        WarehouseRespVO oldItem = BeanUtils.toBean(skuService.getSku(updateReqVO.getId()),WarehouseRespVO.class);
        skuService.updateSku(updateReqVO);
        WarehouseRespVO newItem =BeanUtils.toBean(skuService.getSku(updateReqVO.getId()),WarehouseRespVO.class);
        String oldContent=" 原来数据 "+Arrays.stream(oldItem.getClass().getDeclaredFields()).filter(field->ObjectUtil.isNotNull(field.getAnnotation(ErpOperationField.class))
        ).map(field -> {field.setAccessible(true);try{return field.getAnnotation(ErpOperationField.class).name() + ":" + field.get(oldItem);
        } catch (IllegalAccessException e) {throw new RuntimeException(e);}
        }).collect(Collectors.joining(","));
        String newContent=";修改完数据 "+Arrays.stream(newItem.getClass().getDeclaredFields()).filter(field->ObjectUtil.isNotNull(field.getAnnotation(ErpOperationField.class))
        ).map(field -> {field.setAccessible(true);try{return field.getAnnotation(ErpOperationField.class).name() + ":" + field.get(newItem);
        } catch (IllegalAccessException e) {throw new RuntimeException(e);}
        }).collect(Collectors.joining(","));
        String content=oldContent.concat(newContent);
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("updateSku", SkuSaveReqVO.class));

        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除商品sku")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('erp:sku:delete')")
    @ErpOperationLog(module = "SKU管理",description = "删除sku")
    public CommonResult<Boolean> deleteSku(@RequestParam("id") Long id) throws NoSuchMethodException {
        SkuDO sku = skuService.getSku(id);
        if(ObjectUtil.isNull(sku)){
            throw exceptionErr(500,"sku不存在");
        }
        skuService.deleteSku(id);
        String content=":"+sku.getSku();
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("deleteSku",Long.class));
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得商品sku")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('erp:sku:query')")
    public CommonResult<SkuRespVO> getSku(@RequestParam("id") Long id) {
        SkuDO sku = skuService.getSku(id);
        return success(BeanUtils.toBean(sku, SkuRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得商品sku分页")
    @PreAuthorize("@ss.hasPermission('erp:sku:query')")
    public CommonResult<PageResult<SkuRespVO>> getSkuPage(@Valid SkuPageReqVO pageReqVO) {
        PageResult<SkuDO> pageResult = skuService.getSkuPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, SkuRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出商品sku Excel")
    @PreAuthorize("@ss.hasPermission('erp:sku:export')")
    @ApiAccessLog(operateType = EXPORT)
    @ErpOperationLog(module = "SKU管理",description = "导出商品sku")
    public void exportSkuExcel(@Valid SkuPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<SkuDO> list = skuService.getSkuPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "商品sku.xls", "数据", SkuRespVO.class,
                        BeanUtils.toBean(list, SkuRespVO.class));
    }

    @GetMapping("/import-excel")
    @Operation(summary = "导出入库单 Excel")
    @PreAuthorize("@ss.hasPermission('erp:warehouse-in:import')")
    @ApiAccessLog(operateType = EXPORT)
    @ErpOperationLog(module = "SKU管理",description = "导入商品sku")
    public void importWarehouseInExcel(@RequestParam("file") MultipartFile file,
                                       @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
        List<SkuRespExcel>list=ExcelUtils.read(file,SkuRespExcel.class);
        for (SkuRespExcel skuRespExcel:list){
            String sku = skuRespExcel.getSku();
            BigDecimal length = skuRespExcel.getLength();
            BigDecimal weight = skuRespExcel.getWeight();
            BigDecimal width = skuRespExcel.getWidth();
            BigDecimal height = skuRespExcel.getHeight();
            if(StrUtil.isBlank(sku)){
                throw exceptionErr(500,"sku不能为空");
            }
            SkuDO dbItem = skuService.getSku(sku);
            if(ObjectUtil.isNotNull(dbItem)){
                throw exceptionErr(500,"sku已存在");
            }

            if(Stream.of(length, weight, width, height).anyMatch(e -> ObjectUtil.isNull(e) || e.compareTo(BigDecimal.ZERO) == 0)){
                throw exceptionErr(500,"长|宽|高|重量|不能为空");
            }
        }
        list.forEach(e->{
            String sku = e.getSku();
            SkuDO dbItem = skuService.getSku(sku);
            if(ObjectUtil.isNotNull(dbItem)){
            dbItem.setRemake(e.getRemake());
            dbItem.setLength(e.getLength());
            dbItem.setWeight(e.getWeight());
            dbItem.setWidth(e.getWidth());
            dbItem.setRemake(e.getRemake());
            dbItem.setHeight(e.getHeight());
            skuService.updateSku(BeanUtils.toBean(dbItem,SkuSaveReqVO.class));
            }else {
            SkuSaveReqVO createReqVO = new SkuSaveReqVO();
            createReqVO.setSku(e.getSku());
            createReqVO.setRemake(e.getRemake());
            createReqVO.setLength(e.getLength());
            createReqVO.setWeight(e.getWeight());
            createReqVO.setWidth(e.getWidth());
            createReqVO.setRemake(e.getRemake());
            createReqVO.setHeight(e.getHeight());
            skuService.createSku(createReqVO);
            }

        });
        String content="";
        for(SkuRespExcel e:list) {
            SkuRespVO newItem = BeanUtils.toBean(e, SkuRespVO.class);
            content=Arrays.stream(newItem.getClass().getDeclaredFields()).filter(field->ObjectUtil.isNotNull(field.getAnnotation(ErpOperationField.class))
            ).map(field -> {field.setAccessible(true);
                try {
                    return field.getAnnotation(ErpOperationField.class).name() + ":" + field.get(newItem);
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
            }).collect(Collectors.joining(","))+"\n";
        }
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("createSku",MultipartFile.class,Boolean.class));

    }

 }